package tenumn.energytech.registrys.pipeline;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import tenumn.energytech.registrys.CapabilitiesRegistry;
import tenumn.energytech.registrys.capability.ICapabilityHeart;

import javax.annotation.Nonnull;
import java.util.Objects;

public class HeartPipeBlockEntity extends BlockEntity {
    private Float tmp = null;
    private final LazyOptional<ICapabilityHeart> lazyOptional=LazyOptional.of(()->new ICapabilityHeart() {
        final SimpleHeartNetwork network=SimpleHeartNetwork.Factory.get(HeartPipeBlockEntity.this.level);
        @Override
        public float getTemperature() {
            return Math.min(this.getMax(), this.network.getNetworkHeart(HeartPipeBlockEntity.this.getBlockPos()));
        }

        @Override
        public float rise(float amount, boolean simulate) {
            float temperature = this.getTemperature();
            float diff = Math.min(500, this.getMax() - temperature);
            if (!simulate) {
                this.network.addHeart(HeartPipeBlockEntity.this.getBlockPos(), diff);
                if (diff != 0) {
                    HeartPipeBlockEntity.this.setChanged();
                }
            }
            return diff;
        }

        @Override
        public float coolDown(float amount, boolean simulate) {
            float temperature = this.getTemperature();
            float diff = Math.min(500,temperature);
            if (!simulate) {
                this.network.addHeart(HeartPipeBlockEntity.this.getBlockPos(), -diff);
                if (diff != 0) {
                    HeartPipeBlockEntity.this.setChanged();
                }
            }
            return diff;
        }

        @Override
        public float getMin() {
            return 0;
        }

        @Override
        public float getMax() {
            return 1_000 * this.network.getNetworkSize(HeartPipeBlockEntity.this.getBlockPos());
        }

        @Override
        public boolean canReceive() {
            return true;
        }
    }).cast();
    public HeartPipeBlockEntity(BlockEntityType<?> pType, BlockPos pWorldPosition, BlockState pBlockState) {
        super(pType, pWorldPosition, pBlockState);
    }
    @Nonnull
    @Override
    public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, Direction side) {
        boolean isHeart = Objects.equals(cap, CapabilitiesRegistry.HEART_CAPABILITY);
        return isHeart ? this.lazyOptional.cast() : super.getCapability(cap, side);
    }

    @Override
    public void load(@Nonnull CompoundTag compound) {
        this.tmp = compound.getFloat("WireHeart");
        super.load(compound);
    }

    @Override
    public void saveAdditional(@Nonnull CompoundTag compound) {
        SimpleHeartNetwork network = SimpleHeartNetwork.Factory.get(this.level);
        compound.putFloat("WireHeart", network.getSharedHeart(this.getBlockPos()));
        super.saveAdditional(compound);
    }

    @Override
    public void onLoad() {
        if (this.level != null && !this.level.isClientSide) {
            SimpleHeartNetwork network = SimpleHeartNetwork.Factory.get(this.level);
            if (this.tmp != null) {
                float diff = this.tmp - network.getSharedHeart(this.getBlockPos());
                network.addHeart(this.getBlockPos(), diff);
                this.tmp = null;
            }
            network.enableBlock(this.getBlockPos(), this::setChanged);
        }
        super.onLoad();
    }

    @Override
    public void onChunkUnloaded() {
        if (this.level != null && !this.level.isClientSide) {
            SimpleHeartNetwork network = SimpleHeartNetwork.Factory.get(this.level);
            network.disableBlock(this.getBlockPos(), this::setChanged);
        }
        super.onChunkUnloaded();
    }

    @Override
    public void setRemoved() {
        if (this.level != null && !this.level.isClientSide) {
            SimpleHeartNetwork network = SimpleHeartNetwork.Factory.get(this.level);
            network.disableBlock(this.getBlockPos(), () ->
            {
                float diff = network.getSharedHeart(this.getBlockPos());
                network.addHeart(this.getBlockPos(), -diff);
                this.setChanged();
            });
        }
        super.setRemoved();
    }
}
